var syncFunc = {
    async backup(){
        try{
            // 删除15天前的备份
            if (fs.existsSync(SyncBackupDir) == false){
                fs.mkdirSync(SyncBackupDir,{recursive: true});
            }
            let filesList =  fs.readdirSync(SyncBackupDir);
            let current = new Date();
            if (filesList.length > SyncBackupRemainDays){
                let canDeleteNum = filesList.length - SyncBackupRemainDays;
                for (let i = 0; i< filesList.length; i++){
                    let res = /.*_(\d*)-(\d*)-(\d*)_[\d]*_[\d]*_[\d]*/.exec(filesList[i]);
                    let difference = current - new Date(Number(res[1]), Number(res[2])-1, Number(res[3]));
                    if (Math.floor(difference / 86400000) > SyncBackupRemainDays){
                        let files = fs.readdirSync(`${SyncBackupDir}/${filesList[i]}`);
                        for (let file of files){
                            fs.unlinkSync(`${SyncBackupDir}/${filesList[i]}/${file}`);
                        }
                        fs.rmdirSync(`${SyncBackupDir}/${filesList[i]}`);
                        logger.info(`已删除 ${SyncBackupRemainDays} 天前的备份: ${filesList[i]}`);
                    }
                    canDeleteNum --;
                    if (canDeleteNum <= 0){
                        break;
                    }
                }
            }

            let date = new Date();
            let dateStr = `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}_${date.getHours()}_${date.getMinutes()}_${date.getSeconds()}`;
            let DbFileDir = `${SyncBackupDir}/CENTERDATA_${dateStr}`;
            logger.info(`>> 外置中心数据库开始备份: ${DbFileDir}`);

            let backupDb = new KVDatabase(DbFileDir);
            let keys = await CENTERDATA_db.listKey();

            for (let i = 0; i < keys.length; i++){
                if (await backupDb.set(keys[i], await CENTERDATA_db.get(keys[i])) == false){
                    logger.error(`>> 外置中心数据库备份失败: ${keys[i]} 写入错误`);
                    await backupDb.close();
                    let files = fs.readdirSync(`${SyncBackupDir}/CENTERDATA_${dateStr}`);
                    for (let file of files){
                        fs.unlinkSync(`${SyncBackupDir}/CENTERDATA_${dateStr}/${file}`);
                    }
                    fs.rmdirSync(DbFileDir);
                    return {success:false, output:`>> 外置中心数据库备份失败: ${keys[i]} 写入错误`}; 
                }
            }
            logger.debug(`备份数据键列表: ${keys}`);
            
            logger.info(`>> 外置中心数据库备份成功: ${DbFileDir}`);
            return {success:true, output:`>> 外置中心数据库备份成功: ${DbFileDir}`};
        }catch(e){
            logger.error(e);
        }
        
        
    },
    autoBackup(){
        let _syncFunc = this;
        try{
            if (typeof(SyncBackupTime) == "string"){
                new CronJob(SyncBackupTime, function () { 
                    _syncFunc.backup();
                }, null, true,'Asia/Chongqing');
            }else{
                for (let t of SyncBackupTime){
                    new CronJob(t, function () { 
                        _syncFunc.backup();
                    }, null, true,'Asia/Chongqing');
                }
            }
        }
        catch(e){
            logger.error('启动外置中心数据库自动备份失败, 检查WSSConfig.json BackupTime Cron表达式配置, 不能有问号');
        }
    },

    async getOfflinePlayerSyncData(uuid){
        let playerData = await CENTERTemp_db.get(uuid);
        if (playerData == null ){
            return null;
        }
        let _dbData = await CENTERDATA_db.get(uuid);
        if (_dbData == null ){
            logger.error(`[sync] 外置玩家数据库: 获取玩家数据失败, 没有该玩家存档数据 ${playerData.playerRealName} uuid:${uuid}`);
            return null;
        }
        playerData['playerSyncData'] = _dbData['playerSyncData'];
        return playerData;
    },
    
    async setPlayerData(data_, onlyPlayerInfo = false) {
        if (data_ == null) {
            logger.error('[sync] 外置玩家数据库: 无法写入null数据');
            return false;
        }
        let res = await CENTERDATA_db.set(data_.playerUuid, data_);
        if (res == false){
            logger.error(`[sync] 外置玩家数据库: 写入玩家 <${data_.realName}> 的数据失败。 xuid: ${data_.playerXuid} uuid: ${data_.playerUuid}`);
        }
        delete data_['playerSyncData'];
        res = await CENTERTemp_db.set(data_.playerUuid, data_);
        if (res == false){
            logger.error(`[sync] 外置玩家数据库: 写入玩家 <${data_.realName}> 的缓存信息失败。 xuid: ${data_.playerXuid} uuid: ${data_.playerUuid}`);
        }
        return res;
    },

    async broadcastAllPlayerData(){
        if (SyncInventoryDB != "外置中心数据库"){
            return logger.error("无外置中心数据库, 或修改服务端'SyncInventoryDB'配置。");
        }
        let allDataKey = await CENTERDATA_db.listKey();
        logger.warn(`正在向 ${mcws.OnlineNames} 广播 ${allDataKey.length} 条玩家数据...`);
        let startTime = new Date().getTime();
        for (let uuid of allDataKey){
            let playerData = await CENTERDATA_db.get(uuid);
            let data = {
                tag: "syncDownloadPlayerData",
                //eventid: sync_data.eventid,
                playerData: playerData, //待同步的数据
                // syncConfig: PlayerDbData.syncConfig,
                // mainBDSName: mainBDS.name,
                // mainBDSCnnUid: mainBDS.uid,
                // requestClientUid: thisClient.uid,
                // requestClientName: thisClient.name
            };
            mcws.broadcastJson(data, 'Sync');  
        }
        let totalTime = new Date().getTime() - startTime;
        logger.warn(`传输结束, 已广播 ${allDataKey.length} 条玩家数据 | ${(totalTime/1000).toFixed(2)}s`);
    }
};

module.exports = syncFunc;
